package com.spring.redis.operation.service.base.impl;

import com.spring.redis.operation.service.base.StringRedisBaseService;
import com.spring.redis.operation.utils.RedisOperationUtils;
import lombok.NonNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * redis Operation string class
 *
 * @author zhouyu
 */
@Service
public class StringRedisBaseServiceImpl extends RedisBaseServiceImpl implements StringRedisBaseService {

    private final ValueOperations<String, Object> valueOperations;

    private final ValueOperations<String, String> stringValueOperations;

    public StringRedisBaseServiceImpl(RedisTemplate<String, Object> redisTemplate, ValueOperations<String, Object> valueOperations, ValueOperations<String, String> stringValueOperations) {
        super(redisTemplate);
        this.valueOperations = valueOperations;
        this.stringValueOperations = stringValueOperations;
    }

    /**
     * 存储string类型
     *
     * @param key   key
     * @param value value
     */
    @Override
    public void set(@NonNull String key, @NonNull String value) {
        valueOperations.set(key, value);
    }

    /**
     * 存储string类型，并设置key的有效时间
     *
     * @param key     key
     * @param value   value
     * @param seconds 过期时间，单位秒，为null不过期
     */
    @Override
    public void setEx(@NonNull String key, @NonNull String value, Long seconds) {
        valueOperations.set(key, value);
        expire(key, seconds, TimeUnit.SECONDS);
    }

    /**
     * 存储string类型，并设置key的有效时间
     *
     * @param key      key
     * @param value    value
     * @param expire   自定义过期时间
     * @param timeUnit 时间类型
     */
    @Override
    public void setEx(@NonNull String key, @NonNull String value, @NonNull Long expire, @NonNull TimeUnit timeUnit) {
        valueOperations.set(key, value);
        expire(key, expire, timeUnit);
    }

    /**
     * 获取string类型的值
     *
     * @param key key
     * @return String
     */
    @Override
    public String get(@NonNull String key) {
        Object v = valueOperations.get(key);
        return null == v ? null : v.toString();
    }

    /**
     * 批量获取String类型的值
     *
     * @param keys keys
     * @return java.util.List<String>
     */
    @Override
    public List<String> multiGet(@NonNull String... keys) {
        return RedisOperationUtils.listObjectCastString(valueOperations.multiGet(RedisOperationUtils.arrToSet(keys)));
    }

    /**
     * 递增num，num<0时递减
     *
     * @param key key
     * @param num num
     * @return java.lang.Long
     */
    @Override
    public Long increment(@NonNull String key, Long initNum, @NonNull Long num) {
        if (!hasKey(key)) {
            initNum = initNum == null ? 0L : initNum;
            stringValueOperations.set(key, initNum.toString());
        }
        return stringValueOperations.increment(key, num);
    }

    /**
     * 获取自增自减值
     *
     * @param key key
     * @return java.lang.Long
     */
    @Override
    public Long incrementValue(String key) {
        String strNum = stringValueOperations.get(key);
        if (StringUtils.isEmpty(strNum)) {
            return null;
        }
        return Long.parseLong(strNum);
    }

}
